package com.jzo2o.health.handler;

import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
import com.jzo2o.health.properties.OrdersJobProperties;
import com.jzo2o.health.service.IOrdersRefundService;
import com.jzo2o.health.service.IOrdersService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 订单相关定时任务
 *
 * @author itcast
 * @create 2023/9/2 16:44
 **/
@Slf4j
@Component
public class OrdersHandler {

    @Resource
    private RefundRecordApi refundRecordApi;
    //解决同级方法调用，事务失效问题
    @Resource
    private OrdersHandler orderHandler;
    @Resource
    private OrdersJobProperties ordersJobProperties;

    @Autowired
    private IOrdersService iOrdersService;
    /**
     * 支付超时取消订单
     * 每分钟执行一次
     */
    @XxlJob(value = "cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {
        //1.查询pay_status=0，当前时间-15分钟小于
        List<Orders> ordersList = iOrdersService.lambdaQuery()
                .lt(Orders::getCreateTime, LocalDateTime.now().minusMinutes(15))//小于等于当前时间-15分钟
                .eq(Orders::getPayStatus, OrderPayStatusEnum.NO_PAY.getStatus())
                .eq(Orders::getOrderStatus, OrderStatusEnum.NO_PAY.getStatus())
                .list();
        if (CollUtils.isNotEmpty(ordersList)){
            for (Orders orders : ordersList) {
                try {
                    OrdersCancelReqDTO ordersCancelReqDTO=new OrdersCancelReqDTO();
                    ordersCancelReqDTO.setId(orders.getId());//设置订单id
                    ordersCancelReqDTO.setCancelReason("超时未支付");
                    iOrdersService.cancel(ordersCancelReqDTO,true);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }
    }


    @Autowired
    private ApplicationContext applicationContext;
    /**
     * 订单退款异步任务
     */
    @XxlJob(value = "handleRefundOrders")
    public void handleRefundOrders() {
        OrdersHandler ordersHandler = applicationContext.getBean(OrdersHandler.class);
        //查询
        List<OrdersRefund> ordersRefundList = ordersRefundService.lambdaQuery()
                .last("limit 100")
                .list();
        if (CollUtils.isNotEmpty(ordersRefundList)){
            return;
        }
        //遍历退款
        for (OrdersRefund ordersRefund : ordersRefundList) {
            ordersHandler.ordersRefundHandle(ordersRefund);
        }
    }


@Autowired
private IOrdersRefundService ordersRefundService;

    /**
     * 退款处理
     * @param ordersRefund
     */
    @Transactional(rollbackFor = Exception.class)
    public void ordersRefundHandle(OrdersRefund ordersRefund) {
        ExecutionResultResDTO executionResultResDTO=null;
        try {
             executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
        } catch (Exception e) {
            log.error("[订单退款处理]退款申请接口调用失败，退款信息：{}，异常信息", ordersRefund, e);
            throw new RuntimeException(e);
        }
        //2.从响应结果中获取退款处理状态
        Integer refundStatus = executionResultResDTO.getRefundStatus();
        //3.如果是退款中，则再查询一次退款结果
        if(ObjectUtils.equals(refundStatus, OrderPayStatusEnum.REFUNDING.getStatus())) {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //再发起一次退款请求，就是查询退款结果了
            executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
            refundStatus = executionResultResDTO.getRefundStatus();
    }
        if (OrderPayStatusEnum.PAY_SUCCESS.getStatus().equals(refundStatus)){
            refundStatus=OrderPayStatusEnum.REFUND_SUCCESS.getStatus();
        }
        boolean update = iOrdersService.lambdaUpdate()
                .eq(Orders::getId, ordersRefund.getId()) //更新条件
                //.ne(Orders::getPayStatus, refundStatus)//更新条件
                .set(Orders::getPayStatus, refundStatus) //退款状态
                .set(Orders::getRefundNo, executionResultResDTO.getRefundNo()) //支付服务退款订单号
                .set(Orders::getRefundId, executionResultResDTO.getRefundId()) //第三方退款订单号
                .update();
        if(!update){
            log.error("[订单退款处理]订单表退款状态更新失败，退款信息：{}", ordersRefund);
            return;
        }
        //5.删除退款记录
        boolean resultRefund = ordersRefundService.removeById(ordersRefund.getId());
        if(!resultRefund){
            log.error("[订单退款处理]删除退款记录失败，退款信息：{}", ordersRefund);
        }
}

    /**
     * 订单退款处理
     *
     * @param id                    订单id
     * @param executionResultResDTO 第三方退款信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void refundOrder(Long id, ExecutionResultResDTO executionResultResDTO) {

    }

}
